#include "scene.h"

using namespace std;

Scene::Scene( double nRefr, Color &ambient, Color &background, int depthLim ){
    _nRefr = nRefr;
    _ambient = ambient;
    _background = background;
    _depthLim = depthLim;
    primitives = new Primitive*[1000];
    primitiveCt = 0;
    luminaires = new Luminaire*[1000];
    luminaireCt = 0;
}

void Scene::addLuminaire( Luminaire* lum )
{
    luminaires[luminaireCt++] = lum;
}

Luminaire* Scene::luminaire( int i )
{
    Luminaire* lum;
    if( i<0 || i >= luminaireCt )
        lum = NULL;
    else
        lum = luminaires[i];
    return lum;
}

void Scene::addPrimitive( Primitive* prim )
{
    primitives[primitiveCt++] = prim;
}

Primitive* Scene::ix( const Ray &r, Point &p, Vector &n  )
{
    double DMin = DBL_MAX;
    int primIdx;
    for( int i=0; i<primitiveCt; i++ )
    {
        double D = primitives[i]->ix( r );
        if( D > EPS && D < DMin )
        {
            primIdx = i;
            p = r.p( D );
            n = primitives[i]->n( p, r.t0() );
            DMin =  D;
        }
    }
    if( DMin == DBL_MAX )
        return NULL;
    else
        return primitives[primIdx];
}


Color Scene::trace( Ray r )
{
    if( r.depth() > _depthLim )
        return Color();
    Point p;
    Vector n;
    Primitive* prim = ix( r, p, n );
    if( prim == NULL )
        return _background;
    else
        return prim->mat()->l( this, p, n, r );
}

double Scene::nRefr() const
{
    return _nRefr;
}

Color Scene::ambient() const
{
    return _ambient;
}
